// the includes have to be in the right order, or it won't compile
#include <SlaveData.h>
#include <ST7565.h>
#include "LCD.h"
#include <NewSoftSerial.h>
//#include "Model.h"
#include "RFID.h"

#define DEBUG 0

#define SONAR_PIN 0

// used to save memory for LCD strings
char char_buffer[160];

void setup()   {                

  Lcd.init();
  Rfid.init();
  
  pinMode(SONAR_PIN, INPUT);

  Serial.begin(9600);
  #if DEBUG == 1
  Serial.print("Master start. Free memory (bytes): ");
  Serial.print(freeRam());
  Serial.println(";");
  #endif
}

void loop() {

  // send the sonar value
  Serial.print("SONAR,");
  Serial.print(analogRead(SONAR_PIN));
  Serial.print(";");
  
  //update RFID
  const unsigned char tag = Rfid.readTagIfAvailable();
  if (tag == RFID_NORTH || tag == RFID_SOUTH || tag == RFID_EAST || tag == RFID_WEST) {
    #if DEBUG == 1
    Serial.print("Detected tag: ");
    Serial.println(tag, DEC);
    #endif
    Serial.print("RFID,");
    Serial.print(tag == RFID_NORTH ? NORTH : (tag == RFID_SOUTH ? SOUTH : (tag == RFID_EAST ? EAST : WEST)));
    Serial.println(";");
    activateLCD(tag, 5000);
  } else {
    Serial.print("RFID,null;");
  }

  #if DEBUG == 1
  Serial.println(freeRam());
  #endif 
  
  delay(1000);  

}

// TODO: clean up this function, create "description" strings like the one commented out below
void activateLCD(int tag, int pause) {
  digitalWrite(LCD_BACKLIGHT_LED, HIGH);
  
  glcd.clear();
  strcpy_P(char_buffer, (char*)pgm_read_word(&(catTable[tag-RFID_NORTH])));
  glcd.drawstring(0, 0, char_buffer);
  glcd.display();
  delay(pause / 2);

  glcd.clear();
  strcpy_P(char_buffer, (char*)pgm_read_word(&(dirTable[tag-RFID_NORTH])));
  glcd.drawstring(0, 0, char_buffer);
  glcd.display();
  delay(pause);

  //show a tip on how to save energy
  glcd.clear();
  strcpy_P(char_buffer, (char*)pgm_read_word(&(tipsTable[tag-RFID_NORTH])));
  glcd.drawstring(0, 0, char_buffer);
  glcd.display();
  delay(pause);
  glcd.clear();
  glcd.display();  
  
  digitalWrite(LCD_BACKLIGHT_LED, LOW);
}

// this handy function will return the number of bytes currently free in RAM, great for debugging!   
int freeRam(void)
{
  extern int  __bss_end; 
  extern int  *__brkval; 
  int free_memory; 
  if((int)__brkval == 0) {
    free_memory = ((int)&free_memory) - ((int)&__bss_end); 
  }
  else {
    free_memory = ((int)&free_memory) - ((int)__brkval); 
  }
  return free_memory; 
} 


